using SoapCore;
using System.Net;
using WebApi2.WebServices;

var builder = WebApplication.CreateBuilder(args);
//旧的控制器，其实现在可以不用了
builder.Services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.Converters.Add(new DateTimeConverter()));
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddApiVersioning().AddApiExplorer(options => options.GroupNameFormat = "'v'VVV");
builder.Services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
builder.Services.AddSwaggerGen(options => options.OperationFilter<OpenApiDefaultValues>());
builder.Services.AddProblemDetails();
//新最小Api的json选项配置
builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.Converters.Add(new DateTimeConverter());
});
builder.Services.ConfigureHttpClientDefaults(configure =>
{
    configure.ConfigureHttpClient((serviceProvider, httpClient) => {
        var cameraIp = "172.20.60.34";
        httpClient.BaseAddress = new Uri($"http://{cameraIp}");
    });
    configure.UseSocketsHttpHandler((handler, serviceProvider) =>
    {
        var username = "admin";
        var password = "hk123456";
        //handler.Credentials = new CredentialCache
        //{
        //    { new Uri("http://" + cameraIp), "Digest", new NetworkCredential("admin", "hk123456") }
        //};
        handler.Credentials = new NetworkCredential(username, password);
    });
});

//日志
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(builder.Configuration)
.CreateLogger();
//原来3.5中是这样加的builder.Host.ClearProviders().AddSerilog();
builder.Host.UseSerilog();

builder.Services.AddHostedService<MqttHostService>();
builder.Services.AddSingleton<IContract, StudentService>();
builder.Services.AddHealthChecks()
    .AddCheck("self", () => HealthCheckResult.Healthy());
//.AddUrlGroup(new Uri("http://localhost:123/hc"), name: "catalogapi-check", tags: new string[] { "catalogapi" });
builder.Services.AddSpaStaticFiles(options => options.RootPath = "dist");
builder.Services.AddSingleton<PluginsManagement>();
var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(setup =>
    {
        var pathBase = app.Configuration["PATH_BASE"] ?? string.Empty;

        foreach (var description in app.DescribeApiVersions())
        {
            var name = description.GroupName;
            var url = $"{pathBase}/swagger/{name}/swagger.json";

            setup.SwaggerEndpoint(url, name);
        }

            setup.OAuthClientId("webapi2swaggerui");
            setup.OAuthAppName("WebApi2 Swagger UI");
    });
    app.MapGet("/", () => Results.Redirect("/swagger")).ExcludeFromDescription();
}
else
{
    app.UseSpaStaticFiles();
}
app.UseRouting();
app.UseAuthorization();
var summaries = new[]
{
    "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

app.MapGet("/weatherforecast", async context =>
{
    var address = context.Connection.RemoteIpAddress;
    var port = context.Connection.RemotePort;
    var forecast = Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            DateTime.Now.AddDays(index),
            Random.Shared.Next(-20, 55),
            summaries[Random.Shared.Next(summaries.Length)]
        ))
        .ToArray();
    await context.Response.WriteAsJsonAsync(forecast);
});
app.MapPost("/test-mqtt", async (string data) =>
{
    await MqttService.PublishData(data);
});
app.MapHealthChecks("/hc", new HealthCheckOptions()
{
    Predicate = _ => true,
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
app.MapHealthChecks("/liveness", new HealthCheckOptions
{
    Predicate = r => r.Name.Contains("self")
});
app.MapStaffInfoApiV1();
app.NewVersionedApi("WebApi2")
    .MapCaptureApiV1();//.RequireAuthorization();
app.MapDeviceAdapterApiV1().WithOpenApi();
//旧控制器，现在可以不用了
app.MapControllers();
(app as IEndpointRouteBuilder).UseSoapEndpoint<IContract>("/StudentService.asmx", new SoapEncoderOptions(), SoapSerializer.XmlSerializer);
app.UseEndpoints(endpoints => { });
app.UseSpa(spa =>
{
    //spa.Options.SourcePath = "Client";
    //if (app.Environment.IsDevelopment())
    //{
    //    spa.UseAngularCliServer(npmScript: "start");
    //}
});
app.Logger.LogInformation("AppDomain.CurrentDomain.BaseDirectory: {dir}", System.AppDomain.CurrentDomain.BaseDirectory);
app.Logger.LogInformation("Environment.CurrentDirectory: {dir}", System.Environment.CurrentDirectory);
app.Logger.LogInformation("Directory.GetCurrentDirectory: {dir}", System.IO.Directory.GetCurrentDirectory());
app.Logger.LogInformation("AppContext.BaseDirectory: {dir}", System.AppContext.BaseDirectory);
//最好用这种方式获取路径，这样可以保证调试和发布时都能正确获取到路径，注意用dotnet启动时要指定--contentRoot参数为./
app.Logger.LogInformation("ContentRootPath: {dir}", app.Environment.ContentRootPath);


app.Run();

internal record WeatherForecast(DateTime Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
